/**
 *	@file	pgear_skin.c
 *	@brief	ポケギア　スキン変更アプリ
 *	@author	Miyuki Iwasawa
 *	@date	07.06.21
 *
 */

#include "common.h"
#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/brightness.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/fontproc.h"
#include "system/snd_tool.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/wipe.h"
#include "system/buflen.h"
#include "gflib/touchpanel.h"
#include "field/field_matrix.h"
#include "field/field_place_name.h"
#include "application/app_tool.h"
#include "application/pokegear.h"
#include "msgdata/msg.naix"

#include "../pgear_sys.h"
#include "../pgear_frm.h"
#include "pgskin_sys.h"
#include "pgskin_bg.h"
#include "pgskin_sub.h"
#include "pgskin_key.h"

//プロトタイプ宣言　グローバル
//================================================================
///オーバーレイプロセス定義
PROC_RESULT PGearSkinProc_Init( PROC *proc,int *seq);
PROC_RESULT PGearSkinProc_Main( PROC *proc,int *seq);
PROC_RESULT PGearSkinProc_End( PROC *proc,int *seq);


//プロトタイプ宣言　ローカル
static void skin_InitDataSet(PGSKIN_SYS_WORK* wk);
static void skin_LastDataSet(PGSKIN_SYS_WORK* wk);
//
static int skinseq_AppInit(PGSKIN_SYS_WORK* wk);
static int skinseq_AppMain(PGSKIN_SYS_WORK* wk);
static int skinseq_AppEnd(PGSKIN_SYS_WORK* wk);
static int skinseq_SkinSelect(PGSKIN_SYS_WORK* wk);
static int skinseq_SkinChange(PGSKIN_SYS_WORK* wk);
static int skinseq_AllFadeIn(PGSKIN_SYS_WORK* wk);
static int skinseq_AllFadeOut(PGSKIN_SYS_WORK* wk);
static int skinseq_ViewFadeIn(PGSKIN_SYS_WORK* wk);
static int skinseq_ViewFadeOut(PGSKIN_SYS_WORK* wk);



//================================================================
/**
 *	@brief	ポケギア スキンプロセス初期化
 *	@param	proc	プロセスデータ
 *	@param	seq		シーケンス
 *
 *	@return	処理状況
 */
PROC_RESULT PGearSkinProc_Init( PROC *proc,int *seq)
{
	PGSKIN_SYS_WORK *wk = NULL;
	PGEAR_SYS_WORK * sys_wk = (PGEAR_SYS_WORK*)PROC_GetParentWork(proc);

	//ワークエリア取得
	HeapStatePush();

	//ヒープ作成
	sys_CreateHeap(HEAPID_BASE_APP,HEAPID_PGEAR_APP,0x20000);

	wk = PROC_AllocWork( proc,sizeof(PGSKIN_SYS_WORK),HEAPID_PGEAR_APP);
	memset(wk,0,sizeof(PGSKIN_SYS_WORK));

	//パラメータ引継ぎ
	wk->sys = sys_wk;
	wk->heapID = HEAPID_PGEAR_APP;

	skin_InitDataSet(wk);

	//サウンド引継ぎ設定
//	Snd_DataSetByScene( SND_SCENE_SUB_TOWNMAP, 0, 0 );

	return PROC_RES_FINISH;
}

/**
 *	@brief	ポケギア　スキンプロセスメイン
 *	@param	proc	プロセスデータ
 *	@param	seq		シーケンス
 *
 *	@return 処理状況
 */
PROC_RESULT PGearSkinProc_Main(PROC* proc,int *seq)
{
	PGSKIN_SYS_WORK* wk = PROC_GetWork(proc);

	switch(*seq){
	case PGSKIN_SEQ_INIT:
		*seq = skinseq_AppInit(wk);
		break;
	case PGSKIN_SEQ_MAIN:
		*seq = skinseq_AppMain(wk);
		break;
	case PGSKIN_SEQ_END:
		*seq = skinseq_AppEnd(wk);
		break;
	case PGSKIN_SEQ_SKIN_SELECT:
		*seq = skinseq_SkinSelect(wk);
		break;
	case PGSKIN_SEQ_SKIN_CHANGE:
		*seq = skinseq_SkinChange(wk);
		break;
	case PGSKIN_SEQ_ALL_FADEIN:
		*seq = skinseq_AllFadeIn(wk);
		break;
	case PGSKIN_SEQ_ALL_FADEOUT:
		*seq = skinseq_AllFadeOut(wk);
		break;
	case PGSKIN_SEQ_VIEW_FADEIN:
		*seq = skinseq_ViewFadeIn(wk);
		break;
	case PGSKIN_SEQ_VIEW_FADEOUT:
		*seq = skinseq_ViewFadeOut(wk);
		break;
	case PGSKIN_SEQ_APP_EXIT:
		return PROC_RES_FINISH;
	}
	return PROC_RES_CONTINUE;
}

/**
 *	@brief	ポケギア　メインプロセス終了
 *
 *	@param	proc	プロセスデータ
 *	@param	seq		シーケンス
 *
 *	@return 処理状況
 */
PROC_RESULT PGearSkinProc_End(PROC* proc,int* seq)
{
	int heapID = 0;
	PGSKIN_SYS_WORK* wk = PROC_GetWork(proc);

	//セーブデータ反映
	skin_LastDataSet(wk);

	//アプリケーション初回呼び出し終了フラグを立てておく
	wk->sys->call_end = 1;

	//ワークエリア開放
	heapID = wk->heapID;
	PROC_FreeWork(proc);

	HeapStatePop();
	HeapStateCheck(heapID);
	sys_DeleteHeap(heapID);

	return PROC_RES_FINISH;
}

/**
 *	@brief	アプリ初期化データ取得
 */
static void skin_InitDataSet(PGSKIN_SYS_WORK* wk)
{
	//システムにアプリワークポインタを通知
	wk->sys->app_vwork = (void*)wk;

	//システムにSysKey2AppKey描画の切替関数ポインタを通知
	wk->sys->to_akey_func = PGSkinSub_ToKeyChange;
//	wk->sys->to_touch_func = PGSkinSub_ToTouchChange;

	//現在の選択スキンとオープンしているスキンを取得
	wk->skin = PGearSv_GetSkin(wk->sys->pg_save);
	wk->skin_f = PGearSv_GetSkinFlagAll(wk->sys->pg_save);

	//今は強制的に全フラグオープン
	wk->skin_f = 0xFF;
	IWASAWA_PRINT(" PokeGear Skin = %d\n",wk->skin);
}

/**
 *	@brief	セーブデータ反映
 */
static void skin_LastDataSet(PGSKIN_SYS_WORK* wk)
{
	PGearSv_SetSkin(wk->sys->pg_save,wk->skin);

	wk->sys->to_akey_func = NULL;
	wk->sys->to_touch_func = NULL;
}

/**
 *	@brief	ポケギアスキン　シーケンス初期化
 */
static int skinseq_AppInit(PGSKIN_SYS_WORK* wk)
{
	if(!PGSkin_AppInit(wk)){
		return PGSKIN_SEQ_INIT;
	}

	if(wk->sys->call_end){
		return PGSKIN_SEQ_VIEW_FADEIN;
	}else{
		return PGSKIN_SEQ_ALL_FADEIN;
	}
}

/**
 *	@brief	ポケギアスキン　シーケンス終了
 */
static int skinseq_AppMain(PGSKIN_SYS_WORK* wk)
{
	int ret = PG_NEXT_NULL;

	ret = PGSkinKey_ContTouch(wk);

	if(ret == PG_NEXT_NULL){
		PGFrame_ChangeKeyModeCheck(wk->sys);

		if(wk->sys->control == PGCONT_SYS){
			ret = PGFrame_SysKeyControl(wk->sys);
		}else{
			ret = PGSkinKey_ContKey(wk);
		}
	}

	switch(ret){
	case PG_NEXT_NULL:
		break;
	case PG_NEXT_EXIT:
		wk->sys->next_mode = ret;
		return PGSKIN_SEQ_ALL_FADEOUT;
	case PG_NEXT_APP_SEQ:
		return PGSKIN_SEQ_SKIN_SELECT;
	default:
		wk->sys->next_mode = ret;
		return PGSKIN_SEQ_VIEW_FADEOUT;
	}
	return PGSKIN_SEQ_MAIN;
}

/**
 *	@brief	ポケギアスキン　シーケンス終了
 */
static int skinseq_AppEnd(PGSKIN_SYS_WORK* wk)
{
	if(!PGSkin_AppEnd(wk)){
		return PGSKIN_SEQ_END;
	}

	return PGSKIN_SEQ_APP_EXIT;
}

/**
 *	@brief	ポケギアスキン　スキンセレクトボックスコントロール
 */
static int skinseq_SkinSelect(PGSKIN_SYS_WORK* wk)
{
	return PGSkin_SkinSelect(wk);
}

/**
 *	@brief	ポケギアスキン　スキン切替
 */
static int skinseq_SkinChange(PGSKIN_SYS_WORK* wk)
{
	if(!PGSkin_SkinChange(wk)){
		return PGSKIN_SEQ_SKIN_CHANGE;
	}
	return PGSKIN_SEQ_MAIN;
}

/**
 *	@brief	ポケギアスキン　フェードイン
 */
static int skinseq_AllFadeIn(PGSKIN_SYS_WORK* wk)
{
	int i;

	switch(wk->main_seq){
	case 0:
		WIPE_SYS_Start(WIPE_PATTERN_WMS,
				WIPE_TYPE_FADEIN,
				WIPE_TYPE_FADEIN,0x0000,COMM_BRIGHTNESS_SYNC,1,wk->heapID
				);
		//BGの表示をOnにする
		for(i = 0;i < 8;i++){
			GF_BGL_VisibleSet(GF_BGL_FRAME0_M+i,VISIBLE_ON);
		}
		//初期パレットを転送
		PaletteTrans_AutoSet(wk->sys->palAnm,TRUE);
		SoftFadePfd(wk->sys->palAnm,FADE_MAIN_BG,16*PGAPP_PALIDX_M,16*PGAPP_PALNUM_M,0,0x0000);
		SoftFadePfd(wk->sys->palAnm,FADE_MAIN_OBJ,16*PGAPPOAM_PALIDX_M,16*PGAPPOAM_PALNUM_M,0,0x0000);
		PaletteFadeTrans( wk->sys->palAnm );
		PaletteTrans_AutoSet(wk->sys->palAnm,FALSE);

		GF_Disp_GX_VisibleControl(GX_PLANEMASK_OBJ,VISIBLE_ON);
		GF_Disp_GXS_VisibleControl(GX_PLANEMASK_OBJ,VISIBLE_ON);
		wk->main_seq++;
		break;
	case 1:
		if(!WIPE_SYS_EndCheck()){
			break;
		}
		wk->main_seq = 0;
		return PGSKIN_SEQ_MAIN;
	}

	return PGSKIN_SEQ_ALL_FADEIN;
}
/**
 *	@brief	ポケギアスキン　フェードアウト
 */
static int skinseq_AllFadeOut(PGSKIN_SYS_WORK* wk)
{
	int i;
	switch(wk->main_seq){
	case 0:
		WIPE_SYS_Start(WIPE_PATTERN_WMS,
				WIPE_TYPE_FADEOUT,
				WIPE_TYPE_FADEOUT,0x0000,COMM_BRIGHTNESS_SYNC,1,wk->heapID
				);
		wk->main_seq++;
		break;
	case 1:
		if(!WIPE_SYS_EndCheck()){
			break;
		}
		//BGの表示をOffにする
		for(i = 0;i < 8;i++){
			GF_BGL_VisibleSet(GF_BGL_FRAME0_M+i,VISIBLE_OFF);
		}
		wk->main_seq = 0;
		return PGSKIN_SEQ_END;
	}

	return PGSKIN_SEQ_ALL_FADEOUT;
}

/**
 *	@brief	ポケギアスキン　アプリ切替フェードイン
 */
static int skinseq_ViewFadeIn(PGSKIN_SYS_WORK* wk)
{
	int i;

	switch(wk->main_seq){
	case 0:
		PaletteTrans_AutoSet(wk->sys->palAnm,TRUE);

		//Brightnessを解除する
		SetBrightness(BRIGHTNESS_NORMAL,
				(PLANEMASK_BG1 | PLANEMASK_BG2 | PLANEMASK_BG3),MASK_MAIN_DISPLAY);

		//BG123の表示をOnにする
		for(i = 0;i < 3;i++){
			GF_BGL_VisibleSet(GF_BGL_FRAME1_M+i,VISIBLE_ON);
			GF_BGL_VisibleSet(GF_BGL_FRAME1_S+i,VISIBLE_ON);
		}
		wk->sys->palEvy = 0;
		wk->main_seq++;
		break;
	case 1:
		if(!PGFrame_MainPalFadeWait(wk->sys,0)){
			break;
		}
		wk->main_seq++;
		break;
	case 2:
		PaletteTrans_AutoSet(wk->sys->palAnm,FALSE);
		wk->sys->palEvy = 0;
		wk->main_seq = 0;
		return PGSKIN_SEQ_MAIN;
	}

	return PGSKIN_SEQ_VIEW_FADEIN;
}
/**
 *	@brief	ポケギアスキン　アプリ切替フェードアウト
 */
static int skinseq_ViewFadeOut(PGSKIN_SYS_WORK* wk)
{
	int i;
	switch(wk->main_seq){
	case 0:
		PaletteTrans_AutoSet(wk->sys->palAnm,TRUE);
		wk->sys->palEvy = 0;
		wk->main_seq++;
		break;
	case 1:
		if(!PGFrame_MainPalFadeWait(wk->sys,1)){
			break;
		}
		wk->main_seq++;
		break;
	case 2:
		//アプリ用パレットを塗りつぶす
		SoftFadePfd(wk->sys->palAnm,FADE_MAIN_BG,16*PGAPP_PALIDX_M,16*PGAPP_PALNUM_M,16,0x0000);
		SoftFadePfd(wk->sys->palAnm,FADE_MAIN_OBJ,16*PGAPPOAM_PALIDX_M,16*PGAPPOAM_PALNUM_M,16,0x0000);
		PaletteFadeTrans( wk->sys->palAnm );

		//BG123の表示をOffにする
		for(i = 0;i < 3;i++){
			GF_BGL_VisibleSet(GF_BGL_FRAME1_M+i,VISIBLE_OFF);
			GF_BGL_VisibleSet(GF_BGL_FRAME1_S+i,VISIBLE_OFF);
		}
		PaletteTrans_AutoSet(wk->sys->palAnm,FALSE);
		wk->sys->palEvy = 0;
		wk->main_seq = 0;
		return PGSKIN_SEQ_END;
	}

	return PGSKIN_SEQ_VIEW_FADEOUT;
}